/*
 * Copyright (c) 2019 , Healthlink All Rights Reserved.
 */

package com.mayday.system.service.impl;

import com.alibaba.fastjson.JSON;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.mayday.system.domain.*;
import com.mayday.system.mapper.ActivitiMapper;
import com.mayday.system.service.ActivitiService;
import org.activiti.bpmn.BpmnAutoLayout;
import org.activiti.bpmn.model.Process;
import org.activiti.bpmn.model.*;
import org.activiti.engine.*;
import org.activiti.engine.history.HistoricActivityInstance;
import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.history.HistoricVariableInstance;
import org.activiti.engine.impl.identity.Authentication;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.runtime.Execution;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.runtime.ProcessInstanceQuery;
import org.activiti.engine.task.Task;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;

/**
 * 工作流接口实现类
 *
 * @author lxq
 * @version 1.0
 * @date 2020/4/2 10:03
 * @since JDK 1.8+
 */
@Service("activitiService")
public class ActivitiServiceImpl implements ActivitiService {

    private static Logger logger = LoggerFactory.getLogger(ActivitiService.class);

    @Resource
    private ProcessEngine processEngine;
    @Resource
    private RuntimeService runtimeService;
    @Resource
    private TaskService taskService;
    @Resource
    private RepositoryService repositoryService;
    @Resource
    private IdentityService identityService;
    @Resource
    private HistoryService historyService;

    @Resource
    private ActivitiMapper activitiDao;
    private static final String BPMN = "bpmn";
    private static final String TASK_START_VAR_NAME = "flowVoStart";
    private static final String TASK_LOCAL_VAR_NAME = "flowVo";
    private static final String ACTIVITY_TYPE_USER_TASK = "userTask";


    @Override
    public PageInfo<ProcessdefVo> queryProcessdefs(ProcessdefQueryVo queryVo) {
        PageHelper.startPage(queryVo.getPageNum(), queryVo.getPageSize());
        List<ProcessdefVo> list = activitiDao.queryProcessdefs(queryVo);
        return new PageInfo<>(list);
    }

    @Override
    public byte[] queryProcessdefPngByDefId(String defId) throws IOException {

        ProcessDefinition pd = repositoryService.createProcessDefinitionQuery().processDefinitionId(defId).singleResult();
        InputStream in = repositoryService.getResourceAsStream(pd.getDeploymentId(), pd.getDiagramResourceName());

        ByteArrayOutputStream swapStream = new ByteArrayOutputStream();
        byte[] buff = new byte[100];
        int rc = 0;
        while ((rc = in.read(buff, 0, 100)) > 0) {
            swapStream.write(buff, 0, rc);
        }

        return swapStream.toByteArray();
    }

    @Override
    public String addFlowDef(FlowDef flowDef) {
        String flowKey = flowDef.getFlowKey();
        boolean act = flowKey.contains("act_");
        if (!act){
            flowKey = "act_"+flowKey;
        }
        flowDef.setFlowKey("act_" + flowDef.getFlowKey());
        BpmnBuilder builder = new BpmnBuilder();
        BpmnModel bpmnModel = builder.build(flowDef);
        //1.创建运行服务对象
        RuntimeService rs = processEngine.getRuntimeService();
        //2.创建查询流程实例
        ProcessInstanceQuery piq = rs.createProcessInstanceQuery();
        //3.查询是否存在进行中的流程
        List<ProcessInstance> list = piq.processDefinitionKey(flowKey).list();
        //4-1.没有说明已经结束
        if (list.size() == 0) {
            Deployment deployment = deployProcessDef(flowDef, bpmnModel);
            return deployment.getId();
        }
        //4-2.有说明正在进行
        else {
            throw new SecurityException("流程已存在审核中的单据，请先处理单据审核");
        }
    }

    @Override
    public List<RoleAndStaffResp> queryRoleByCenterId(String systemId, String centerId) {
        return activitiDao.queryRoleByCenterId(systemId, centerId);
    }

    @Override
    public List<RoleAndStaffResp> queryStaffByCenterId(String centerId) {
        return activitiDao.queryStaffByCenterId(centerId);
    }

    @Override
    public UserTaskVo operaTask(EmdcFlowVo vo){
        vo.setDefId("act_" + vo.getDefId());
        UserTaskVo userTask;
        ProcessDefinition pd = repositoryService.createProcessDefinitionQuery()
                .processDefinitionKey(vo.getDefId())
                .processDefinitionTenantId(vo.getCenterId())
                .latestVersion()
                .singleResult();
        if (pd == null) {
            throw new SecurityException("找不到流程定义ProcessDefinition");
        }
        if (vo.getIsFirst()) {
            // 新建任务，查询流程是否已经开始审核
            Task taskVerify = taskService.createTaskQuery().processInstanceBusinessKey(vo.getBusinessKey()).singleResult();
            if (taskVerify != null) {
                logger.warn("流程已在审核中{}", vo.getBusinessKey());
                throw new SecurityException("流程已在审核中,请不要重复提交");
            } else {
                identityService.setAuthenticatedUserId(vo.getStaffId());
                Map<String, Object> vars = new HashMap<>(3);
                //vars.put(TASK_START_VAR_NAME, vo);
                vars.put("orgId",1);
                ProcessInstance processInstance = runtimeService.startProcessInstanceById(pd.getId(), vo.getBusinessKey(), vars);

                Task task = taskService.createTaskQuery().processInstanceBusinessKey(vo.getBusinessKey()).singleResult();
                vo.setActive("提交申请");
                vo.setProcessInstanceId(processInstance.getProcessInstanceId());
                userTask = completeCurrentTask(vo, pd, task);
            }
        } else {
//            Task task = taskService.createTaskQuery()
//                    .processDefinitionId(pd.getId())
//                    .processInstanceBusinessKey(vo.getBusinessKey())
//                    .singleResult();
            Task task = taskService.createTaskQuery()
                    .processDefinitionId(pd.getId())
                    .processInstanceBusinessKey(vo.getBusinessKey())
                    .taskCandidateUser(vo.getStaffId())
                    .singleResult();
            if (ObjectUtils.isEmpty(task)) {
                logger.warn("您不能操作此任务");
                throw new SecurityException("您不能操作此任务");
            }
            vo.setActive("再次提交");
            userTask = completeCurrentTask(vo, pd, task);
        }

        return userTask;
    }

    @Override
    public boolean revoke(EmdcFlowVo emdcFlowVo) throws SecurityException {
        String businessKey = emdcFlowVo.getBusinessKey();
        String staffId = emdcFlowVo.getStaffId();
        Task task = taskService.createTaskQuery().processInstanceBusinessKey(businessKey).singleResult();
        if (task == null) {
            logger.warn("流程未启动或已执行完成，无法撤回{}", businessKey);
            throw new SecurityException("流程未启动或已执行完成，无法撤回");
        }

        List<HistoricTaskInstance> htiList = historyService.createHistoricTaskInstanceQuery()
                .processInstanceBusinessKey(businessKey)
                .orderByTaskCreateTime()
                .asc()
                .list();
        String myTaskId = null;
        HistoricTaskInstance myTask = null;
        for (HistoricTaskInstance hti : htiList) {
            if (staffId.equals(hti.getAssignee())) {
                myTaskId = hti.getId();
                myTask = hti;
                break;
            }
        }
        if (null == myTaskId) {
            logger.warn("该任务{}非当前用户{}提交，无法撤回", businessKey, staffId);
            throw new SecurityException("该任务非当前用户提交，无法撤回");
        }

        try {
            // 打回给第一次提交的人
            String myActivityId = null;
            List<HistoricActivityInstance> haiList = historyService.createHistoricActivityInstanceQuery()
                    .executionId(myTask.getExecutionId()).finished().list();
            for (HistoricActivityInstance hai : haiList) {
                if (myTaskId.equals(hai.getTaskId())) {
                    myActivityId = hai.getActivityId();
                    break;
                }
            }

            emdcFlowVo.setActive("撤回");
            UserTaskVo userTaskVo = jumpNode(myActivityId, task, emdcFlowVo);
            List<String> staffs = new ArrayList<>();
            staffs.add(staffId);
            addCandidateUser(userTaskVo.getTaskId(), staffs);
            return true;
        } catch (SecurityException be) {
            logger.error("撤回失败，请稍后重试: {}", be);
            throw new SecurityException("撤回失败，请稍后重试");
        }
    }

    @Override
    public UserTaskVo commitReturnNode(EmdcFlowVo emdcFlowVo) throws SecurityException {
        Task task = taskService.createTaskQuery().processInstanceBusinessKey(emdcFlowVo.getBusinessKey()).singleResult();
        if (task == null) {
            logger.warn("流程未启动或已执行完成，无法重新提交到被驳回节点{}", emdcFlowVo.getBusinessKey());
            throw new SecurityException("流程未启动或已执行完成，无法重新提交到被驳回节点");
        }

        try {
            // 获取当前任务的最后一个审核的节点
            String returnActivityId = null;
            List<HistoricActivityInstance> haiList = historyService.createHistoricActivityInstanceQuery()
                    .executionId(task.getExecutionId()).finished().orderByHistoricActivityInstanceEndTime().desc().list();
            if (haiList != null && haiList.size() > 0) {
                for (HistoricActivityInstance hai : haiList) {
                    if (ACTIVITY_TYPE_USER_TASK.equals(hai.getActivityType())) {
                        returnActivityId = hai.getActivityId();
                        break;
                    }
                }
            }
            emdcFlowVo.setActive("重新提交至驳回人");
            return jumpNode(returnActivityId, task, emdcFlowVo);
        } catch (SecurityException be) {
            logger.error("重新提交到被驳回节点失败，请稍后重试: {}", be);
            throw new SecurityException("重新提交到被驳回节点失败，请稍后重试");
        }
    }

    @Override
    public void addCandidateUser(String taskId, List<String> list) {
        for (String staffId : list) {
            taskService.addCandidateUser(taskId, staffId);
        }
    }

    @Override
    public Integer queryTaskNumByDefKey(String centerId, String defKey, String staffId) {
        ProcessDefinition pd = repositoryService.createProcessDefinitionQuery()
                .processDefinitionKey("act_" + defKey)
                .processDefinitionTenantId(centerId)
                .latestVersion()
                .singleResult();

        int total;
        if (StringUtils.isEmpty(staffId)) {
            total = (int) taskService.createTaskQuery()
                    .processDefinitionId(pd.getId())
                    .count();
        } else {
            total = (int) taskService.createTaskQuery()
                    .processDefinitionId(pd.getId())
                    .taskCandidateUser(staffId)
                    .count();
        }

        return total;
    }

    @Override
    public Integer queryTaskNumBySystemId(String centerId, String systemId, String staffId) {
        List<ProcessDefinition> pds = repositoryService.createProcessDefinitionQuery()
                .processDefinitionTenantId(centerId)
                .processDefinitionCategory(systemId)
                .latestVersion()
                .list();

        int total = 0;
        for (ProcessDefinition pd : pds) {
            if (StringUtils.isEmpty(staffId)) {
                total = total + (int) taskService.createTaskQuery()
                        .processDefinitionId(pd.getId())
                        .count();
            } else {
                total = total + (int) taskService.createTaskQuery()
                        .processDefinitionId(pd.getId())
                        .taskCandidateUser(staffId)
                        .count();
            }
        }

        return total;
    }

    @Override
    public List<EmdcFlowVo> queryTaskAround(String businessKey) {
        List<EmdcFlowVo> resultList = new ArrayList<>(4);
        HistoricProcessInstance hpi = historyService.createHistoricProcessInstanceQuery().processInstanceBusinessKey(businessKey).singleResult();
        if (hpi != null) {
            List<HistoricVariableInstance> list = historyService.createHistoricVariableInstanceQuery().variableName(TASK_LOCAL_VAR_NAME).processInstanceId(hpi.getId()).list();
            list.forEach(historicVariableInstance -> {
                if (!StringUtils.isEmpty(historicVariableInstance.getTaskId())) {
                    EmdcFlowVo obj = (EmdcFlowVo) historicVariableInstance.getValue();
                    if (null == obj.getCreateTime()) {
                        obj.setCreateTime(historicVariableInstance.getCreateTime());
                    }
                    resultList.add(obj);
                }
            });

            Collections.sort(resultList, (o1, o2) -> {
                if (o1.getCreateTime().getTime() < o2.getCreateTime().getTime()) {
                    return 1;
                } else if (o1.getCreateTime().getTime() > o2.getCreateTime().getTime()) {
                    return -1;
                } else {
                    return 0;
                }

            });
        }

        return resultList;
    }

//    @Override
//    public List<ComboBoxVO> querySystemByPlatform(Integer platformId) {
//        return activitiDao.querySystemByPlatform(platformId);
//    }

    @Override
    public List<String> queryFlowAllStaffs(String businessKey) {
        List<HistoricTaskInstance> htiList = historyService.createHistoricTaskInstanceQuery()
                .processInstanceBusinessKey(businessKey)
                .orderByTaskCreateTime()
                .asc()
                .list();

        List<String> auditUsers = new ArrayList<>();
        for (HistoricTaskInstance hti : htiList) {
            if (!StringUtils.isEmpty(hti.getAssignee())) {
                auditUsers.add(hti.getAssignee());
            }
        }
        Set<String> set = new HashSet<>();
        set.addAll(auditUsers);
        auditUsers.clear();
        auditUsers.addAll(set);

        return auditUsers;
    }

    @Override
    public List<UserTask> queryAllUserTaskInfo(String defId) {
        List<UserTask> list = new ArrayList<>();
        BpmnModel bpmnModel = repositoryService.getBpmnModel(defId);
        if (bpmnModel != null) {
            Collection<FlowElement> flowElements = bpmnModel.getMainProcess().getFlowElements();
            for (FlowElement fe : flowElements) {
                if (fe instanceof UserTask) {
                    UserTask ut = (UserTask) fe;
                    if (!ut.getId().equalsIgnoreCase("userTask1")) {
                        list.add(ut);
                    }
                }
            }
        }
        return list;
    }

    @Override
    public String queryIdByKey(String key) {
        return activitiDao.queryIdByKey(key);
    }

    /**
     * 完成当前任务
     *
     * @param vo 请求参数
     * @return List<UserTask>
     * @throws SecurityException
     */
    private UserTaskVo completeCurrentTask(EmdcFlowVo vo, ProcessDefinition pd, Task task) throws SecurityException {
        Map<String, Object> vars = new HashMap<>(3);
        vo.setActiveNode(task.getName());
        if (null != vo.getPass()) {
            if (vo.getPass() == 1) {
                vo.setActive("审核通过");
                vars.put("pass", true);
            } else {
                vo.setActive("驳回");
                vars.put("pass", false);
            }
        }
        vars.put(TASK_LOCAL_VAR_NAME, vo);
        taskService.setVariablesLocal(task.getId(), vars);
        taskService.setAssignee(task.getId(), vo.getStaffId());
        taskService.complete(task.getId(), vars);

        HistoricProcessInstance historicTaskInstance = historyService.createHistoricProcessInstanceQuery().processInstanceBusinessKey(vo.getBusinessKey()).finished().singleResult();
        if (null != historicTaskInstance) {
            // 审核结束
            return null;
        } else {
            // 审核 驳回

            // 取得已提交的任务
            HistoricTaskInstance historicTaskInstance1 = historyService.createHistoricTaskInstanceQuery().taskId(task.getId()).singleResult();

            //获得当前流程的活动ID
            Execution execution = runtimeService.createExecutionQuery().executionId(historicTaskInstance1.getExecutionId()).singleResult();
            String activityId = execution.getActivityId();
            UserTask userTask = (UserTask) repositoryService.getBpmnModel(pd.getId()).getMainProcess().getFlowElement(activityId);
            Task task2 = taskService.createTaskQuery().executionId(execution.getId()).singleResult();

            List<String> listUser = new ArrayList<>();
            List<String> listRole = new ArrayList<>();
            listUser.addAll(userTask.getCandidateUsers());
            listRole.addAll(userTask.getCandidateGroups());

            // 如果是驳回则设置最初提交人为候选人
            if (vo.getPass() != null && vo.getPass() == 0) {
                List<HistoricTaskInstance> historicTaskInstanceList = historyService.createHistoricTaskInstanceQuery()
                        .executionId(historicTaskInstance1.getExecutionId())
                        .orderByHistoricTaskInstanceStartTime().asc().list();

                String commitStaffId = historicTaskInstanceList.get(0).getAssignee();
                if (!StringUtils.isEmpty(commitStaffId)) {
                    listUser.clear();
                    listUser.add(commitStaffId);
                }
            }

            UserTaskVo userTaskVo = new UserTaskVo();
            // 将userTaskId换成taskId, 方便操作
            userTaskVo.setTaskId(task2.getId());
            userTaskVo.setStaffs(listUser);
            userTaskVo.setRoles(listRole);
            logger.warn("completeCurrentTask userTaskVo：{}", JSON.toJSONString(userTaskVo));
            return userTaskVo;
        }
    }

    /**
     * 发布流程
     *
     * @param flowDef 构建流程数据
     * @param model   BpmnModel数据
     * @return 流程实例
     */
    private Deployment deployProcessDef(FlowDef flowDef, BpmnModel model) {

        Deployment deployment = processEngine
                .getRepositoryService()
                .createDeployment()
                .addBpmnModel(flowDef.getFlowName() + BPMN, model)
                .name(flowDef.getFlowName())
                .category(flowDef.getSystemId())
                .key(flowDef.getFlowKey())
                .tenantId(flowDef.getCenterId())
                .deploy();
        return deployment;
    }

    /**
     * 任意跳转到某节点
     *
     * @param activityId 目标节点的id
     * @param task       当前任务信息
     * @param emdcFlowVo 请他数据
     * @return UserTaskVo   下个节点的节点信息（主要是user和group）
     */
    private UserTaskVo jumpNode(String activityId, Task task, EmdcFlowVo emdcFlowVo) {
        // 查询流程定义
        String processDefinitionId = task.getProcessDefinitionId();
        BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinitionId);

        // 获取当前节点和需要跳跃的节点
        FlowNode myFlowNode = (FlowNode) bpmnModel.getMainProcess().getFlowElement(activityId);
        Execution execution = runtimeService.createExecutionQuery().executionId(task.getExecutionId()).singleResult();
        FlowNode flowNode = (FlowNode) bpmnModel.getMainProcess().getFlowElement(execution.getActivityId());

        //记录原活动方向
        List<SequenceFlow> oriSequenceFlows = new ArrayList<>();
        oriSequenceFlows.addAll(flowNode.getOutgoingFlows());

        //清理活动方向
        flowNode.getOutgoingFlows().clear();

        //建立新方向
        List<SequenceFlow> newSequenceFlowList = new ArrayList<>();
        SequenceFlow newSequenceFlow = new SequenceFlow();
        newSequenceFlow.setId("newSequenceFlowId");
        newSequenceFlow.setSourceFlowElement(flowNode);
        newSequenceFlow.setTargetFlowElement(myFlowNode);
        newSequenceFlowList.add(newSequenceFlow);
        flowNode.setOutgoingFlows(newSequenceFlowList);

        //完成任务
        Authentication.setAuthenticatedUserId(emdcFlowVo.getStaffId());
        emdcFlowVo.setActiveNode(myFlowNode.getName());
        emdcFlowVo.setCenterId(task.getTenantId());
        Map<String, Object> vars = new HashMap<>(3);
        vars.put(TASK_LOCAL_VAR_NAME, emdcFlowVo);

        taskService.setVariablesLocal(task.getId(), vars);
        taskService.setAssignee(task.getId(), emdcFlowVo.getStaffId());
        taskService.complete(task.getId(), vars);

        // 查询提交节点的人返回
        UserTask userTask = (UserTask) myFlowNode;
        Task task2 = taskService.createTaskQuery().executionId(task.getExecutionId()).singleResult();

        UserTaskVo userTaskVo = new UserTaskVo();
        userTaskVo.setTaskId(task2.getId());
        userTaskVo.setStaffs(userTask.getCandidateUsers());
        userTaskVo.setRoles(userTask.getCandidateGroups());

        //恢复原方向
        flowNode.setOutgoingFlows(oriSequenceFlows);
        logger.warn("jumpNode userTaskVo：{}", JSON.toJSONString(userTaskVo));
        return userTaskVo;
    }

    @Override
    public Boolean remove(EmdcFlowVo emdcFlowVo) throws SecurityException {
        String businessKey = emdcFlowVo.getBusinessKey();
        String staffId = emdcFlowVo.getStaffId();
        Task task = taskService.createTaskQuery().processInstanceBusinessKey(businessKey).singleResult();
        if (task == null) {
            throw new SecurityException("流程未启动或已执行完成，无法撤回");
        }

        List<HistoricTaskInstance> htiList = historyService.createHistoricTaskInstanceQuery()
                .processInstanceBusinessKey(businessKey)
                .orderByTaskCreateTime()
                .asc()
                .list();
        String myTaskId = null;
        for (HistoricTaskInstance hti : htiList) {
            if (staffId.equals(hti.getAssignee())) {
                myTaskId = hti.getId();
                break;
            }
        }
        if (myTaskId == null) {
            throw new SecurityException("该任务非当前用户提交，无法撤回");
        }

        boolean isSuccess = true;
        try {
            runtimeService.deleteProcessInstance(task.getProcessInstanceId(), "未提交就撤回");
            taskService.deleteTask(task.getId());
            historyService.deleteHistoricTaskInstance(task.getProcessInstanceId());
            historyService.deleteHistoricProcessInstance(task.getProcessInstanceId());
        } catch (Exception e) {
            isSuccess = false;
        }

        return isSuccess;
    }
    private StartEvent createStartEvent() {
        StartEvent startEvent = new StartEvent();
        startEvent.setId("start");
        return startEvent;
    }

    /**
     * end userTask
     * @return EndEvent
     */
    private EndEvent createEndEvent() {
        EndEvent endEvent = new EndEvent();
        endEvent.setId("end");
        return endEvent;
    }
    private ExclusiveGateway creatExclusiveGateway(String id) {
        ExclusiveGateway exclusiveGateway = new ExclusiveGateway();
        exclusiveGateway.setId(id);
        return exclusiveGateway;
    }
    @Override
    public BpmnModel buildDynamicProcess() {
        BpmnModel bpmnModel = new BpmnModel();
        Process process = new Process();
        bpmnModel.addProcess(process);
        process.setId("act_a442765a-5218-47a0-8fce-db802d2f08e2");
        process.setName("进销存-应急物资申请");
        process.addFlowElement(createStartEvent());
        process.addFlowElement(createEndEvent());
        UserTask applicantTask = createUserTask("applicantTask", "申请人", null);
        process.addFlowElement(applicantTask);
        // 动态节点
        ExclusiveGateway dynamicTask = creatExclusiveGateway("dynamicTask");
        process.addFlowElement(dynamicTask);

        // 区域负责人节点
        UserTask areaManagerTask = createUserTask("areaManagerTask", "区域负责人", "280");
        process.addFlowElement(areaManagerTask);

        // 直属上级节点
        UserTask directSupervisorTask = createUserTask("directSupervisorTask", "直属上级", "130");
        process.addFlowElement(directSupervisorTask);

        // 分中心负责人节点
        UserTask centerManagerTask = createUserTask("centerManagerTask", "分中心负责人", "102");
        process.addFlowElement(centerManagerTask);

        UserTask leaderTask = createUserTask("leaderTask", "分管领导", "100");
        process.addFlowElement(leaderTask);


        // 中心库管员节点
        UserTask centralLibrarianTask = createUserTask("centralLibrarianTask", "中心库管员", "727146c6-3a78-4dd9-8073-0519e427e7f5");
        process.addFlowElement(centralLibrarianTask);

        // 科长节点
        UserTask sectionChiefTask = createUserTask("sectionChiefTask", "科长", "6d024224-f4a4-4e5c-9035-d95cad8c0650");
        process.addFlowElement(sectionChiefTask);

        process.addFlowElement(createSequenceFlow("start", "applicantTask", null, null));
        process.addFlowElement(createSequenceFlow("applicantTask", "dynamicTask", null, null));

        // 动态节点到区域负责人节点或直属上级节点，根据申请人的 orgId 动态选择
        process.addFlowElement(createSequenceFlow("dynamicTask", "areaManagerTask", "${orgId == '1'}", "条件1"));
        process.addFlowElement(createSequenceFlow("dynamicTask", "directSupervisorTask", "${orgId == '2'}", "条件2"));


        // 区域负责人到分中心负责人节点
        process.addFlowElement(creatExclusiveGateway("exclusiveGatewayId1"));
        process.addFlowElement(createSequenceFlow("areaManagerTask", "exclusiveGatewayId1", null, null));
        process.addFlowElement(createSequenceFlow("exclusiveGatewayId1", "centerManagerTask", "${pass}", "通过"));

        // 分中心负责人到中心库管员节点
        process.addFlowElement(creatExclusiveGateway("exclusiveGatewayId2"));
        process.addFlowElement(createSequenceFlow("centerManagerTask", "exclusiveGatewayId2", null, null));
        process.addFlowElement(createSequenceFlow("exclusiveGatewayId2", "centralLibrarianTask", "${pass}", "通过"));




        // 直属上级到分管领导节点
        process.addFlowElement(creatExclusiveGateway("exclusiveGatewayId3"));
        process.addFlowElement(createSequenceFlow("directSupervisorTask", "exclusiveGatewayId3", null, null));
        process.addFlowElement(createSequenceFlow("exclusiveGatewayId3", "leaderTask", "${pass}", "通过"));

        // 分管领导到中心库管员节点
        process.addFlowElement(creatExclusiveGateway("exclusiveGatewayId4"));
        process.addFlowElement(createSequenceFlow("leaderTask", "exclusiveGatewayId4", null, null));
        process.addFlowElement(createSequenceFlow("exclusiveGatewayId4", "centralLibrarianTask", "${pass}", "通过"));



        ;
        // 中心库管员到科长节点
        process.addFlowElement(creatExclusiveGateway("exclusiveGatewayId5"));
        process.addFlowElement(createSequenceFlow("centralLibrarianTask", "exclusiveGatewayId5", null, null));
        process.addFlowElement(createSequenceFlow("exclusiveGatewayId5", "sectionChiefTask", "${pass}", "通过"));


        process.addFlowElement(creatExclusiveGateway("exclusiveGatewayId6"));
        process.addFlowElement(createSequenceFlow("sectionChiefTask", "exclusiveGatewayId6", null, null));
        process.addFlowElement(createSequenceFlow("exclusiveGatewayId6", "end", "${pass}", "通过"));




        process.addFlowElement(createSequenceFlow("exclusiveGatewayId1", "applicantTask", "${!pass}", "不通过"));
        process.addFlowElement(createSequenceFlow("exclusiveGatewayId2", "applicantTask", "${!pass}", "不通过"));
        process.addFlowElement(createSequenceFlow("exclusiveGatewayId3", "applicantTask", "${!pass}", "不通过"));
        process.addFlowElement(createSequenceFlow("exclusiveGatewayId4", "applicantTask", "${!pass}", "不通过"));
        process.addFlowElement(createSequenceFlow("exclusiveGatewayId5", "applicantTask", "${!pass}", "不通过"));
        process.addFlowElement(createSequenceFlow("exclusiveGatewayId6", "applicantTask", "${!pass}", "不通过"));


        FlowDef flowDef = new FlowDef();
        flowDef.setFlowName("进销存-应急物资申请");
        flowDef.setSystemId("20");
        flowDef.setFlowKey("act_a442765a-5218-47a0-8fce-db802d2f08e2");
        flowDef.setCenterId("443b074d-6e3a-44d3-9d43-f5d79d840654");

        new BpmnAutoLayout(bpmnModel).execute();

        deployProcessDef(flowDef, bpmnModel);
        return bpmnModel;
    }

    private UserTask createUserTask(String id, String name, String assignee) {
        UserTask userTask = new UserTask();
        userTask.setId(id);
        userTask.setName(name);
        if (!Objects.isNull(assignee)){
            if ("areaManagerTask".equals(id) || "directSupervisorTask".equals(id) || "centerManagerTask".equals(id) || "leaderTask".equals(id)) {
                // 使用角色作为候选组
                userTask.setCandidateGroups(Collections.singletonList(assignee));
            } else {
                // 设置申请人为任务的负责人
                userTask.setCandidateUsers(Collections.singletonList(assignee));
            }
        }
        return userTask;
    }

    private SequenceFlow createSequenceFlow(String from, String to, String conditionExpression, String conditionExpressionDesc) {
        SequenceFlow flow = new SequenceFlow();
        flow.setSourceRef(from);
        flow.setTargetRef(to);

        if (conditionExpression != null) {
            flow.setConditionExpression(conditionExpression);
            flow.setName(conditionExpressionDesc);
        }
        return flow;
    }
}
